libxl: Hold the atfork lock while closing carefd
authorIan Jackson <ian.jackson@eu.citrix.com>
Mon, 24 Feb 2014 14:19:14 +0000 (14:19 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Thu, 13 Mar 2014 12:50:07 +0000 (12:50 +0000)
This avoids the process being forked while a carefd is recorded in the
list but the actual fd has been closed.  If that happened, a
subsequent libxl_postfork_child_noexec would attempt to close the fd
again.  If we are lucky that results in a harmless warning; but if we
are unlucky the fd number has been reused and we close an unrelated
fd.

This race has not been observed anywhere as far as we are aware.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
Acked-by: Ian Campbell <Ian.Campbell@citrix.com>
CC: George Dunlap <george.dunlap@eu.citrix.com>
tools/libxl/libxl_fork.c

index 8421296d8dc624e152091dce18bc63680a717a66..fa150959adcfa6618342ba1eb0085cbba5f75d0a 100644 (file)
@@ -184,9 +184,9 @@ void libxl_postfork_child_noexec(libxl_ctx *ctx)
 int libxl__carefd_close(libxl__carefd *cf)
 {
     if (!cf) return 0;
+    atfork_lock();
     int r = cf->fd < 0 ? 0 : close(cf->fd);
     int esave = errno;
-    atfork_lock();
     LIBXL_LIST_REMOVE(cf, entry);
     atfork_unlock();
     free(cf);